
var  sockstate = -1;
function WSocket(url) {
  this.wsUri = url; 

  sockstate = 0;
  $("#status").html("Connecting ...");
  this.websocket = new WebSocket(this.wsUri);
  this.websocket.onopen = function(evt) { onOpen(evt) };
  this.websocket.onclose = function(evt) { onClose(evt) };
  this.websocket.onmessage = function(evt) { onMessage(evt) };
  this.websocket.onerror = function(evt) { onError(evt) };
}

WSocket.prototype = {
  writeDebug: function(msg, level) {
    writeDebug("WSocket: " + msg, level);
  },


  send: function(message) {
    if(sockstate === 1) {
      this.websocket.send(message);
    }
    else {
      $("#status").html("Please connect to start sharing");
      this.writeDebug("Please connect to the server", 5);
    }
  },

  send2: function(type, subtype, opaque) {
    var data = {
      type: type,
      subtype: subtype,
      groupname: User.groupName,
      username: User.userName,
      gid: gid,
      uid: User.uid,
      opaque: opaque
    };

    if(sockstate === 1) {
      this.websocket.send(JSON.stringify(data));
    }
  },
}
  
  //events on socket
  
function onOpen(evt) { 
  $("#status").html("Connected");
  sockstate = 1;
  syncOpen();
} 


function onClose(evt) { 
  $("#status").html("Disconnected");
  syncClose();
  sockstate = -1;
}


function onError(evt) { 
  this.writeDebug("ERROR: " + evt.data, 2);
  syncClose();
  sockstate = -1;
  viewer = 0;
  owner = 0;
}


function onMessage(evt) {
  var data = JSON.parse(evt.data);

  this.writeDebug("onMessage: raw data: " + evt.data, 9);

  if(data.type == "chat") {
    this.writeDebug(data.opaque.message, 5);
    var str = "<span style='color: blue;'>" + data.opaque.message + "</span>";
    $("#chatoutput").append(str);
    $('#chatoutput').attr('scrollTop', $('#chatoutput').attr('scrollHeight'));
    $("#chat_btn").effect("highlight", {}, 500, function(){});
    
  }
  else if(data.type == "pen") {

    if(data.event == "pendown") {

      //save current style
      cctx.save();

      this.writeDebug("onMessage: md x " + data.pt.X + " y " + data.pt.Y, 5);
      cctx.beginPath();
      cctx.moveTo(data.pt.X, data.pt.Y);
    }
    else if(data.event == "penmove") {
      this.writeDebug("onMessage: mm x " + data.pt.X + " y " + data.pt.Y, 9);
      cctx.lineTo(data.pt.X, data.pt.Y);
      cctx.stroke();
    }
    else if(pt.mouseevent == "penup") {
      this.writeDebug("onMessage: mu x " + data.pt.X + " y " + data.pt.Y, 5);
      cctx.closePath();

      //restore the style back
      cctx.restore();
      this.writeDebug("onMessage: md restore style lc " + cctx.strokeStyle , 5);
    }
    else {
      this.writeDebug("onMessage: unknown mouseevent x " + pt.x + " y " + pt.y, 3);
    }
  }

  //sync messages go here
  else if(data.type === "sync") {
    syncRecv(data);
  }

  else if(data.type === "bbox") {
    if(data.flag == "new") {
      get_bbox();
      boxes[data.id].create(data.box.xmin, data.box.ymin,
                          data.box.worig, data.box.horig);
      boxes[data.id].path = data.box.path;
      //try deep copy
      //boxes[data.id].path = JSON.parse(JSON.stringify(data.box.path));
    }
    else if(data.flag === "remove") {
      free_bbox(data.id);
    }
    else if(data.flag === "resize" || data.flag === "move") {
      boxes[data.id].x = data.box.x;
      boxes[data.id].y = data.box.y;
      boxes[data.id].w = data.box.w;
      boxes[data.id].h = data.box.h;
      boxes[data.id].xmin = data.box.xmin;
      boxes[data.id].ymin = data.box.ymin;
      boxes[data.id].worig = data.box.worig;
      boxes[data.id].horig = data.box.horig;
    }
    else if(data.flag === "reset") {
      LB.Canvas.reset();
    }
    else {
    }
  }
  else if(data.type === "path") {
    if(data.flag === "new") {
      var p = new Path();
      p.path = data.path.path;
      p.strokeStyle = data.path.strokeStyle;
      p.lineWidth = data.path.lineWidth;
      LB.Book.pushObject(p);
      data = {};
    }
    else if(data.flag === "undo") {
      LB.Canvas.Events.undo();
    }
    else if(data.flag === "redo") {
      LB.Canvas.Events.redo();
    }
  }
  else if(data.type === "text") {
    if(data.flag === "new") {
      var t = new Text();
      t.x = data.text.x;
      t.y = data.text.y;
      t.text = data.text.text;
      t.fillStyle = data.text.strokeStyle;
      LB.Book.pushObject(t);
      data = {};
    }
    else if(data.flag === "undo") {
      LB.Canvas.Events.undo();
    }
    else if(data.flag === "redo") {
      LB.Canvas.Events.redo();
    }
  }

  else {
    this.writeDebug("onMessage: unknown pkt type " + pt.type, 3);
  }
  LB.Canvas.redrawCanvas();
}
